package com.ylz.sjzx.sio.room.thread;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.ylz.sjzx.sio.common.mid.cache.redis.JedisTemplate;
import com.ylz.sjzx.sio.common.core.constant.Const;
import com.ylz.sjzx.sio.common.core.context.ApplicationUtils;
import com.ylz.sjzx.sio.common.core.enums.Cmd;
import com.ylz.sjzx.sio.common.core.enums.MessageType;
import com.ylz.sjzx.sio.common.core.enums.Role;
import com.ylz.sjzx.sio.common.core.utils.GsonUtil;
import com.ylz.sjzx.sio.common.core.utils.GsonUtil2;
import com.ylz.sjzx.sio.room.entity.HistoryMessage;
import com.ylz.sjzx.sio.room.entity.LoginMessageResp;
import com.ylz.sjzx.sio.room.entity.User;
import com.ylz.sjzx.sio.room.repository.Room2Repository;
import com.ylz.sjzx.sio.room.repository.RoomRepository;
import com.ylz.sjzx.sio.room.repository.SessionRepository;
import com.ylz.sjzx.sio.room.utils.UserUtil;
import com.ylz.sjzx.sio.sdk.client.core.IMNioBase;
import com.ylz.sjzx.sio.sdk.client.engine.ChatEngineManager;
import com.ylz.sjzx.sio.sdk.client.session.IMSession;
import com.ylz.sjzx.sio.sdk.client.session.UserSession;
import com.ylz.sjzx.sio.sdk.client.utils.ChatRoomMessageUtil;
import com.ylz.sjzx.sio.sdk.client.utils.SessionUtil;
import com.ylz.sjzx.sio.sdk.model.BaseSocketModel;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 登录成功后的主动业务
 */
@Slf4j
public class LoginProcess {

    private static String loginMessage = "用户${realname}进入了${roomName}班级${groupName}小组";

    private IMSession session;
    private String appEnvironment = ApplicationUtils.getProperty("base.environment.value");

    public LoginProcess(IMSession session) {
        this.session = session;
    }

    public void doRun() {
        // 0.学生进入聊天室  2.检查禁言3.检查是否全班禁言  4 查看老师是否发布过公告 5.查看老师正在倒计时 6.获取历史消息
        //7.历史消息
        //8.普通学生进小组，老师辅师进管理组
        //
        //.mq发送消息记录
        // 6.获取历史消息
        //获取历史问题
        UserSession userSession = SessionUtil.getUserSessionService().getOrAddByUserId(session.getUserId());
        try {
            ChatEngineManager.add2ChatRoomGroup(session);
        } catch (Exception e) {
            userSession.unLockLogin();
            log.error("加入聊天室失败 断开", e);
            //移除基础信息 防止处理登出业务
            SessionRepository.remove(session);
            session.getSocketIOClient().disconnect();
            return;
        }
        this.loginMsg();
        JedisTemplate.me()
                .zSet(Const.PREFIX_YKT + session.getRoomName() + ":" + session.getHostAddress(), session.getUserId(),
                        System.currentTimeMillis());
        //获取本次登录imsession
        IMSession imsession1 = IMNioBase.getGlobalSession().get(session.getSid());
        if (imsession1 == null || imsession1.rightSocket() == null) {
            return;
        }
        //判断是否是出于物理连接状态 有些并发操作会导致断开事件比登录事件快 如果断开比连接快 那么本次imSession直接作废
        synchronized (imsession1.getObjectLock()) {
            if (imsession1.getSessionState() > IMSession.STATE_CONNECT_SOCKET) {
                //未处于物理连接状态 已经进行了登录操作 作废
                log.info("==sid={}登入操作,未登录已经登出===连接作废", session.getSid());
                return;
            }
            imsession1.setSessionState(IMSession.STATE_CONNECT_SESSION);
            SessionRepository.save(session);
        }
        this.getHistoryQuestion();

        if (Const.MKOP.equals(this.appEnvironment)) {
            this.getHistoryByMk();
        } else {
            this.getHistory();
        }

        this.denyUser();

        this.denyClass();
        this.notice();
        this.countdown();
        this.group();
        userSession.unLockLogin();
        log.info("====sid={},uid={},===loginIn成功解锁===", session.getSid(), session.getUserId());

    }

    /**
     * 第一个方法特殊 重试机制保障一定消息发送成功
     */
    private void getHistoryQuestion() {
        Map map = Room2Repository.historyQuestion(this.session);
        Collection questionsCollection = map.values();
        UserUtil
                .sendMesage(this.session,
                        BaseSocketModel.builder().action(Cmd.historyQuestion).param(questionsCollection).needtoParam(true)
                                .build());
    }

    private void getHistory() {
        Set<String> message = Room2Repository.getMessage(this.session, -20, -1);
        UserUtil
                .sendMesage(this.session,
                        BaseSocketModel.builder().action(Cmd.history).param(message).needtoParam(true).build());
    }

    /**
     * 市场直播 获取历史消息
     */
    private void getHistoryByMk() {
        Set<String> message = Room2Repository.getMessage(this.session, -100, -1);
        if (Role.te.getValue().equals(this.session.getRole().getValue()) ||
                Role.tu.getValue().equals(this.session.getRole().getValue())) {
            UserUtil.sendMesage(this.session, BaseSocketModel.builder().action(Cmd.history).
                    param(message).needtoParam(true).build());
        } else {
            //            Set<String> messages = new HashSet<>();
            List<String> messageList = new ArrayList<>();
            message.forEach(a -> {
                HistoryMessage historyMessage = GsonUtil.json2Bean(a, HistoryMessage.class);
                if (this.session.getGroupName().equals(historyMessage.getGroupName()) ||
                        "1".equals(historyMessage.getGroupName())) {
                    messageList.add(a);
                }
            });
            UserUtil.sendMesage(this.session, BaseSocketModel.builder().action(Cmd.history).
                    param(messageList).needtoParam(true).build());
        }
    }

    private void group() {

        // 存入在线名单
        RoomRepository.saveOnlineList(this.session, UserUtil.getUser(this.session));
        RoomRepository.save2RoomGroup(this.session);
        if (!this.session.isStudent()) {
            //获取在线人员名单
            Map onlineList = RoomRepository.onlineList(this.session);
            UserUtil.sendMesage(this.session,
                    BaseSocketModel.builder().action(Cmd.onlineList).param(onlineList).needtoParam(true).build());

            // 获取禁言名单
            Map<Object, Object> denyList = RoomRepository.denyList(this.session);
            List list = new ArrayList();
            for (Map.Entry entry : denyList.entrySet()) {
                list.add(entry.getValue());
            }
            UserUtil.sendMesage(this.session,
                    BaseSocketModel.builder().action(Cmd.denyList)
                            .param(CollectionUtil.isEmpty(list) ? "empty" : list).needtoParam(true).build());
        }
    }

    private void countdown() {
        String countdown = RoomRepository.countdown(this.session);
        if (StrUtil.isNotBlank(countdown)) {
            UserUtil.sendMesage(this.session,
                    BaseSocketModel.builder().action(Cmd.countdown).
                            param(GsonUtil2.json2Bean(countdown, Map.class)).needtoParam(true).build());
        }
    }

    private void notice() {
        String notice = RoomRepository.notice(this.session);
        if (StrUtil.isNotBlank(notice)) {
            UserUtil.sendMesage(this.session,
                    BaseSocketModel.builder().param(GsonUtil.json2Bean(notice, Map.class)).
                            needtoParam(true).action(Cmd.getNotice).build());
        }
    }

    private void denyUser() {
        String deny = RoomRepository.deny(this.session);
        if (StrUtil.isNotBlank(deny)) {
            UserUtil.sendMesage(this.session,
                    BaseSocketModel.builder().action(Cmd.denyUser).build());
        }
    }

    private void denyClass() {
        String denyClass = RoomRepository.denyClass(this.session);
        if (StrUtil.isNotBlank(denyClass)) {
            UserUtil
                    .sendMesage(this.session,
                            BaseSocketModel.builder().action(Cmd.denyClass).build());
        }
    }

    private void loginMsg() {
        User user = new User();
        user.setUserId(this.session.getUserId());
        user.setRole(this.session.getRole());
        user.setRealname(this.session.getRealname());
        Map onlineList = RoomRepository.onlineList(this.session);
        LoginMessageResp loginMessageResp = LoginMessageResp.builder().action(Cmd.loginMsg)
                .user(user)
                .clientsLen(onlineList.size() + 1)
                .build();
        //向聊天室admin广播
        BaseSocketModel baseSocketModel =
                BaseSocketModel.builder().action(Cmd.loginMsg).param(loginMessageResp).needtoParam(true).build();
        //学生的话自己接收
        if (Const.MKOP.equals(this.appEnvironment)) {
            //发送给所有人
            ChatRoomMessageUtil.sendMessage(session, MessageType.ALL, baseSocketModel);
        } else {
            //学生的话自己接收
            if (session.isStudent()) {
                UserUtil.sendMesage(session, baseSocketModel);
            }
            //发送给admin
            ChatRoomMessageUtil.sendMessage(session, MessageType.ADMIN, baseSocketModel);
        }


    }
}
